package com.daxia.bumall.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.daxia.bumall.basemodel.CoreUser;
import com.daxia.bumall.common.Entry;
import com.daxia.bumall.common.ProductCategoryStatus;
import com.daxia.bumall.dto.ProductCategoryDTO;
import com.daxia.bumall.dto.UserDTO;
import com.daxia.bumall.model.ProductCategory;
import com.daxia.bumall.service.AdService;
import com.daxia.bumall.service.AddressService;
import com.daxia.bumall.service.ApiModuleService;
import com.daxia.bumall.service.ApiTestParameterService;
import com.daxia.bumall.service.ApiTestService;
import com.daxia.bumall.service.BizConfigService;
import com.daxia.bumall.service.BrandService;
import com.daxia.bumall.service.BrandStyleService;
import com.daxia.bumall.service.BrowseRecordService;
import com.daxia.bumall.service.CartService;
import com.daxia.bumall.service.CityService;
import com.daxia.bumall.service.CommunityHouseTypeService;
import com.daxia.bumall.service.CommunityService;
import com.daxia.bumall.service.CompanyService;
import com.daxia.bumall.service.DecorateNoteCommentService;
import com.daxia.bumall.service.DecorateNoteDetailService;
import com.daxia.bumall.service.DecorateNoteService;
import com.daxia.bumall.service.DecorateRequirementService;
import com.daxia.bumall.service.DepartmentService;
import com.daxia.bumall.service.DesignCollectionService;
import com.daxia.bumall.service.DesignProductService;
import com.daxia.bumall.service.DesignService;
import com.daxia.bumall.service.DesignerFanService;
import com.daxia.bumall.service.DesignerInfoService;
import com.daxia.bumall.service.DesignerService;
import com.daxia.bumall.service.DispatcherService;
import com.daxia.bumall.service.DistrictService;
import com.daxia.bumall.service.EventDispather;
import com.daxia.bumall.service.FactoryInfoService;
import com.daxia.bumall.service.GzActivityService;
import com.daxia.bumall.service.HouseStyleService;
import com.daxia.bumall.service.HouseTypeService;
import com.daxia.bumall.service.IExcelCallback;
import com.daxia.bumall.service.LocationService;
import com.daxia.bumall.service.OrderDesignerService;
import com.daxia.bumall.service.OrderItemService;
import com.daxia.bumall.service.OrderService;
import com.daxia.bumall.service.PayDetailService;
import com.daxia.bumall.service.PayService;
import com.daxia.bumall.service.ProductCategoryService;
import com.daxia.bumall.service.ProductCategorySpaceService;
import com.daxia.bumall.service.ProductCategoryTagService;
import com.daxia.bumall.service.ProductCollectService;
import com.daxia.bumall.service.ProductPropertiesService;
import com.daxia.bumall.service.ProductService;
import com.daxia.bumall.service.ProfitService;
import com.daxia.bumall.service.ProvinceService;
import com.daxia.bumall.service.SeedService;
import com.daxia.bumall.service.SpaceObjectService;
import com.daxia.bumall.service.SpaceService;
import com.daxia.bumall.service.SpecificationService;
import com.daxia.bumall.service.StoreService;
import com.daxia.bumall.service.TagService;
import com.daxia.bumall.service.TaskService;
import com.daxia.bumall.service.TimelineCommentService;
import com.daxia.bumall.service.TimelineLikeService;
import com.daxia.bumall.service.TimelineService;
import com.daxia.bumall.service.UserDesignDetailService;
import com.daxia.bumall.service.UserDesignService;
import com.daxia.bumall.service.UserHeadImagesService;
import com.daxia.bumall.service.UserService;
import com.daxia.bumall.service.UserTaskRecordService;
import com.daxia.bumall.service.UserTaskService;
import com.daxia.bumall.service.ValidateCodeService;
import com.daxia.bumall.util.DateUtils;
import com.daxia.bumall.util.DevUtils;
import com.daxia.bumall.util.MyWebUtils;
import com.daxia.bumall.util.SpringSecurityUtils;

public class BaseController extends CoreBaseController {
    @Autowired
    protected UserDesignDetailService userDesignDetailService;

    @Autowired
    protected UserDesignService userDesignService;

    @Autowired
    protected ProductCategorySpaceService productCategorySpaceService;

    @Autowired
    protected SpaceObjectService spaceObjectService;

    @Autowired
    protected SpaceService spaceService;

    @Autowired
    protected GzActivityService gzActivityService;

    @Autowired
    protected BrowseRecordService browseRecordService;

    @Autowired
    protected ProductCollectService productCollectService;

	@Autowired
	protected DispatcherService dispatcherService;
    @Autowired
    protected BrandStyleService brandStyleService;

    @Autowired
    protected ProfitService profitService;

    @Autowired
    protected DepartmentService departmentService;

	@Autowired
	protected EventDispather eventDispather;
    @Autowired
    protected SeedService seedService;

    @Autowired
    protected ProductCategoryTagService productCategoryTagService;

    @Autowired
    protected UserHeadImagesService userHeadImagesService;

    @Autowired
    protected PayService payService;

    @Autowired
    protected CommunityHouseTypeService communityHouseTypeService;

    @Autowired
    protected CommunityService communityService;

    @Autowired
    protected UserTaskRecordService userTaskRecordService;

    @Autowired
    protected UserTaskService userTaskService;

    @Autowired
    protected TaskService taskService;

    @Autowired
    protected DecorateNoteCommentService decorateNoteCommentService;

    @Autowired
    protected DecorateNoteService decorateNoteService;

    @Autowired
    protected DecorateNoteDetailService decorateNoteDetailService;

    @Autowired
    protected CompanyService companyService;

    @Autowired
    protected DesignerInfoService designerInfoService;

    @Autowired
    protected FactoryInfoService factoryInfoService;

    @Autowired
    protected BizConfigService bizConfigService;

    @Autowired
    protected AdService adService;

    @Autowired
    protected CityService cityService;

    @Autowired
    protected ProvinceService provinceService;

    @Autowired
    protected ValidateCodeService validateCodeService;

    @Autowired
    protected ApiTestParameterService apiTestParameterService;

    @Autowired
    protected ApiTestService apiTestService;

    @Autowired
    protected ApiModuleService apiModuleService;

    @Autowired
    protected TimelineLikeService timelineLikeService;

    @Autowired
    protected TimelineCommentService timelineCommentService;

    @Autowired
    protected TimelineService timelineService;

    @Autowired
    protected DecorateRequirementService decorateRequirementService;

    @Autowired
    protected DesignerService designerService;

    @Autowired
    protected OrderDesignerService orderDesignerService;

    @Autowired
    protected DesignCollectionService designCollectionService;

    @Autowired
    protected DesignerFanService designerFanService;

    @Autowired
    protected DesignProductService designProductService;

    @Autowired
    protected DesignService designService;

    @Autowired
    protected HouseStyleService houseStyleService;

    @Autowired
    protected HouseTypeService houseTypeService;

    @Autowired
    protected AddressService addressService;

    @Autowired
    protected CartService cartService;

    @Autowired
    protected PayDetailService payDetailService;

    @Autowired
    protected OrderItemService orderItemService;

    @Autowired
    protected DistrictService districtService;

    @Autowired
    protected OrderService orderService;

    @Autowired
    protected SpecificationService specificationService;

    @Autowired
    protected ProductPropertiesService productPropertiesService;

    @Autowired
    protected ProductService productService;

    @Autowired
    protected StoreService storeService;

    @Autowired
    protected ProductCategoryService productCategoryService;

    @Autowired
    protected TagService tagService;

    @Autowired
    protected BrandService brandService;

   
	@Autowired
	protected UserService userService;
	
	@Autowired
	protected LocationService locationService;
	
	@Autowired
	protected HttpServletRequest request;
	
    protected UserDTO getUserFromSession() {
        if (DevUtils.isLocal()) {
            return userService.load(13L);
        }
        UserDTO user = null;
        Long userIdFromSession = (Long) MyWebUtils.getCurrentRequest().getSession().getAttribute("wx.userId");
        if (userIdFromSession != null) {
            user = userService.load(userIdFromSession);
        }
        return user;
    }

    protected void setUserToSession(UserDTO user) {
        if (user != null) {
            MyWebUtils.getCurrentRequest().getSession().setAttribute("wx.userId", user.getId());
        }
    }
    
    
    protected String getRequestUrlWithQueryString() {
        String url = MyWebUtils.getCurrentRequest().getRequestURL().toString();
        String q = MyWebUtils.getCurrentRequest().getQueryString();
        if (StringUtils.isNotBlank(q)) {
            url += "?" + q;
        }
        return url;
    }
    
    protected <T> Entry<String, String> toExcel(String path, String fileName, List<T> data, IExcelCallback<T> callback) throws IOException {
    	HSSFWorkbook  wb = new HSSFWorkbook();
		HSSFSheet  sheet = wb.createSheet();
        HSSFPatriarch patriarch =  sheet.createDrawingPatriarch();
        Row header = callback.header(sheet);
        int rownum = null == sheet ? 0 : sheet.getLastRowNum() + 1;
        for (T obj : data) {
            Row row = sheet.createRow(rownum);
            Row _row = callback.convert(wb,patriarch,row, obj);
            rownum = _row.getRowNum() + 1;
        }
        callback.footer(sheet);
        callback.layout(sheet);
        java.util.Date date = new java.util.Date();
        String fname = String.format("%s_%s", fileName, DateUtils.format(date, "yyyyMMddHHmmss"));
        FileOutputStream fileOut = new FileOutputStream(path + fname + ".xls");
        wb.write(fileOut);
        fileOut.close();
        return new Entry<String, String>(fname + ".xls", path + fname + ".xls");
    }
    
  //通用读取excel方法
    protected List<Map<String, Object>> readExcelFile(String filepath) {
        Workbook wb = null;
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        try {
            InputStream is = new FileInputStream(new File(filepath));
            wb = WorkbookFactory.create(is);
            Sheet sheet = wb.getSheetAt(0);
            int firstRowIndex = sheet.getFirstRowNum();
            int lastRowIndex = sheet.getLastRowNum();
            for (int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) {
                Row row = sheet.getRow(rIndex);
                Map<String, Object> item = new HashMap<String, Object>();
                if (row != null) {
                    int lastCellIndex = row.getLastCellNum();
                    for (int cIndex = 0; cIndex < lastCellIndex; cIndex++) {
                        Cell cell = row.getCell(cIndex);
                        Object val = getCellValue(cell);
                        if (null != val) {
                            item.put("col_" + (cIndex + 1), val);
                        }
                    }
                }
                if (!item.isEmpty()) {
                    result.add(item);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }



    private  Object getCellValue(Cell cell) {
        if (cell != null) {
            switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_STRING:
                return cell.getStringCellValue();
            case HSSFCell.CELL_TYPE_NUMERIC:
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date date = cell.getDateCellValue();
                    return date;
                } else {
                    cell.setCellType(Cell.CELL_TYPE_STRING);
                    String temp = StringUtils.trimToEmpty(cell
                            .getStringCellValue());
                    return (temp.indexOf(".") != -1) ? Double.parseDouble(temp)
                            : temp;
                }
            case HSSFCell.CELL_TYPE_FORMULA:
                String strVal = cell.getStringCellValue();
                return StringUtils.isBlank(strVal) ? strVal : cell
                        .getNumericCellValue();
            case HSSFCell.CELL_TYPE_BOOLEAN:
                return cell.getBooleanCellValue();
            case HSSFCell.CELL_TYPE_BLANK:
                break;
            case HSSFCell.CELL_TYPE_ERROR:
                break;
            default:
                break;
            }
        }
        return null;
    }
    
    @ResponseBody
    @ExceptionHandler
    public String onException(Exception e) {
    	e.printStackTrace();
    	JSONObject json = new JSONObject();
    	json.put("success", false);
    	json.put("msg", e.getMessage());
    	return json.toJSONString();
    }
    
    @ResponseBody
    public String okJson() {
    	JSONObject json = new JSONObject();
    	json.put("success", true);
    	return json.toJSONString();
    }
    public String ok() {
    	JSONObject json = new JSONObject();
    	json.put("success", true);
    	return json.toJSONString();
    }
    public String ok(String msg) {
    	JSONObject json = new JSONObject();
    	json.put("success", true);
    	json.put("msg", msg);
    	return json.toJSONString();
    }
    
    protected void head(Map<String, Object> map) {
    	List<ProductCategoryDTO> categories = productCategoryService.findRoot(5);
    	map.put("categories", categories);    	
    }
    
    protected UserDTO getCurrentUserDTO() {
    	CoreUser coreUser = SpringSecurityUtils.getCurrentUser();
    	if (coreUser == null) {
    		return null;
    	}
    	return userService.load(coreUser.getId());
    }
    
    public void getShowCategories(Map<String, Object> map) {
    	List<ProductCategoryDTO> categories = productCategoryService.findAllRoot();
    	map.put("categories", categories);
    }
    
    /**
     * 获取当前项目路径
     * @return
     */
    public String getRealPath(){
    	return request.getSession().getServletContext().getRealPath("");
    }
    
    protected String ok(JSONArray array) {
    	JSONObject data = new JSONObject();
    	data.put("success", true);
    	data.put("data", array);
		return data.toJSONString();
	}
    
    protected void prepareCategories(Map<String, Object> map) {
    	List<ProductCategoryDTO> categories = productCategoryService.findAllRoot();
    	for (int i = categories.size() - 1; i >= 0; i--) {
    		ProductCategoryDTO root = categories.get(i);
			if (root.getStatus() == null || root.getStatus() == ProductCategoryStatus.Inactive.getValue()) {
				categories.remove(i);
				continue;
			}
			for (int j = root.getChildren().size() - 1; j >= 0; j--) {
				ProductCategory c = root.getChildren().get(j);
				if (c.getStatus() == null || c.getStatus() == ProductCategoryStatus.Inactive.getValue()) {
					root.getChildren().remove(j);
					continue;
				}
				
				for (int k = c.getChildren().size() - 1; k >= 0; k--) {
					ProductCategory cc = c.getChildren().get(k);
					if (cc.getStatus() == null || cc.getStatus() == ProductCategoryStatus.Inactive.getValue()) {
						c.getChildren().remove(k);
					}
				}
			}
		}
    	map.put("categories", categories);
	}
}
